package com.zhangxin.aiInterview.manager.xfapi.websocket.llmmodel;

import com.google.gson.Gson;
import com.zhangxin.aiInterview.common.ErrorCode;
import com.zhangxin.aiInterview.exception.BusinessException;
import com.zhangxin.aiInterview.manager.disruptor.WsEventProducer;
import com.zhangxin.aiInterview.manager.xfapi.websocket.llmmodel.model.RoleContent;
import lombok.extern.slf4j.Slf4j;
import okhttp3.HttpUrl;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import org.jetbrains.annotations.NotNull;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * LLM ws消息监听器
 */
@Slf4j
@Deprecated
public class LLmWs extends WebSocketListener {
    // 对话历史存储集合
    public static final Map<Long,List<RoleContent>> historyMap=new HashMap<>();
    // 最终答案
    public static String totalAnswer="";
    public static final Gson gson = new Gson();

    private final Long userId;
    //disruptor生产者
    private final WsEventProducer wsEventProducer;
    // 构造函数
    public LLmWs(Long userId, WsEventProducer wsEventProducer) {
        this.userId = userId;
        this.wsEventProducer = wsEventProducer;
    }

    /**
     * 防止对话上下文过长
     * @param userId
     * @return
     */
    public static boolean canAdd(Long userId){
        //获取当前用户的对话上下文
        List<RoleContent> historyList = historyMap.get(userId);
        // 由于历史记录最大上线1.2W左右，需要判断是能能加入历史
        int _length=0;
        for(RoleContent temp:historyList){
            _length=_length+temp.getContent().length();
        }
        if(_length>12000) {
            historyList.remove(0);
            historyList.remove(1);
            historyList.remove(2);
            historyList.remove(3);
            historyList.remove(4);
        }
        return true;
    }

    /**
     * 建立连接成功回调函数
     * @param webSocket 当前ws连接
     * @param response
     */
    @Override
    public void onOpen(WebSocket webSocket, Response response) {
        super.onOpen(webSocket, response);
        //管理连接
        System.out.println("llm ws连接已建立");
        //初始化用户上下文
        if(!historyMap.containsKey(userId)){
            historyMap.put(userId,new ArrayList<>());
        }
    }

    /**
     * 接收到消息回调函数
     * @param webSocket 当前ws连接
     * @param text
     */
    @Override
    public void onMessage(WebSocket webSocket, String text) {
        //获取用户的对话上下文
        List<RoleContent> historyList = historyMap.get(userId);
        JsonParse myJsonParse = gson.fromJson(text, JsonParse.class);
        if (myJsonParse.header.code != 0) {
            System.out.println("发生错误，错误码为：" + myJsonParse.header.code);
            System.out.println("本次请求的sid为：" + myJsonParse.header.sid);
            webSocket.close(1000, "");
        }
        List<Text> texthistory = myJsonParse.payload.choices.text;
        for (Text temp : texthistory) {
            System.out.print(temp.content);
            totalAnswer=totalAnswer + temp.content;
        }
        if (myJsonParse.header.status == 2) {
            log.info("最终答案为："+ totalAnswer);
            // 可以关闭连接，释放资源
            System.out.println();
            System.out.println("*************************************************************************************");
            canAdd(userId);
            //封装ai回答
            RoleContent roleContent=new RoleContent();
            roleContent.setRole("assistant");
            roleContent.setContent(totalAnswer);
            //将信息添加到用户的对话上下文
            historyList.add(roleContent);
            historyMap.put(userId,historyList);
            //将AI的合成文本转换为语音
            try {
                //消息AI合成文本放入disruptor队列
//                log.info("AI合成文本放入disruptor队列");
//                wsEventProducer.publishEvent(userId,"",totalAnswer,true);
            } catch (Exception e) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR,"初始化tts 连接失败");
            }finally {
                webSocket.close(1000, "");
                //重置答案
                totalAnswer="";
                //删除用户连接
                LLmWsManager.removeConnection(userId);
            }
        }
    }

    @Override
    public void onClosed(@NotNull WebSocket webSocket, int code, @NotNull String reason) {
        super.onClosed(webSocket, code, reason);
        System.out.println("llm ws链接已关闭");
    }

    @Override
    public void onFailure(WebSocket webSocket, Throwable t, Response response) {
        super.onFailure(webSocket, t, response);
        try {
            if (null != response) {
                int code = response.code();
                System.out.println("onFailure code:" + code);
                System.out.println("onFailure body:" + response.body().string());
                if (101 != code) {
                    System.out.println("connection failed");
                    System.exit(0);
                }
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    //region
    // 鉴权方法
    public static String getAuthUrl(String hostUrl, String apiKey, String apiSecret) throws Exception {
        URL url = new URL(hostUrl);
        // 时间
        SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
        format.setTimeZone(TimeZone.getTimeZone("GMT"));
        String date = format.format(new Date());
        // 拼接
        String preStr = "host: " + url.getHost() + "\n" +
                "date: " + date + "\n" +
                "GET " + url.getPath() + " HTTP/1.1";
        // SHA256加密
        Mac mac = Mac.getInstance("hmacsha256");
        SecretKeySpec spec = new SecretKeySpec(apiSecret.getBytes(StandardCharsets.UTF_8), "hmacsha256");
        mac.init(spec);

        byte[] hexDigits = mac.doFinal(preStr.getBytes(StandardCharsets.UTF_8));
        // Base64加密
        String sha = Base64.getEncoder().encodeToString(hexDigits);
        // System.err.println(sha);
        // 拼接
        String authorization = String.format("api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"", apiKey, "hmac-sha256", "host date request-line", sha);
        // 拼接地址
        HttpUrl httpUrl = Objects.requireNonNull(HttpUrl.parse("https://" + url.getHost() + url.getPath())).newBuilder().//
                addQueryParameter("authorization", Base64.getEncoder().encodeToString(authorization.getBytes(StandardCharsets.UTF_8))).//
                addQueryParameter("date", date).//
                addQueryParameter("host", url.getHost()).//
                build();

        return httpUrl.toString();
    }

    //返回的json结果拆解
    class JsonParse {
        Header header;
        Payload payload;
    }

    class Header {
        int code;
        int status;
        String sid;
    }

    class Payload {
        Choices choices;
    }

    class Choices {
        List<Text> text;
    }

    class Text {
        String role;
        String content;
    }
    //endregion
}